/*
 * Copyright (c) 2018-2999 广州市蓝海创新科技有限公司 All rights reserved.
 *
 * https://www.mall4j.com/
 *
 * 未经允许，不可做商业用途！
 *
 * 版权所有，侵权必究！
 */

package com.ruoyi.app;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;

import com.ruoyi.app.dto.*;
import com.ruoyi.app.param.ChangeShopCartParam;
import com.ruoyi.app.param.ShopCartParam;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.Arith;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.order.domain.Basket;
import com.ruoyi.order.service.IBasketService;
import com.ruoyi.product.domain.Product;
import com.ruoyi.product.domain.Sku;
import com.ruoyi.product.service.IProductService;
import com.ruoyi.product.service.ISkuService;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.AllArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import org.springframework.web.bind.annotation.*;


import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author lanhai
 */
@RestController
@RequestMapping("/p/shopCart")
@Tag(name = "购物车接口")
@AllArgsConstructor
public class AppShopCartController extends BaseController {
    @Autowired
    private IBasketService basketService;
    @Autowired
    private IProductService productService;
    @Autowired
    private ISkuService skuService;
    private final ApplicationContext applicationContext;
    @Autowired
    private TokenService tokenService;
    /**
     * 获取用户购物车信息
     *
     * @param basketIdShopCartParamMap 购物车参数对象列表
     * @return
     */
    @PostMapping("/info")
    @Operation(summary = "获取用户购物车信息", description = "获取用户购物车信息，参数为用户选中的活动项数组,以购物车id为key")
    public AjaxResult info(@RequestBody Map<Long, ShopCartParam> basketIdShopCartParamMap, HttpServletRequest request) {
        LoginUser user = tokenService.getLoginUser(request);

        // 更新购物车信息，
        if (MapUtil.isNotEmpty(basketIdShopCartParamMap)) {
            basketService.updateBasketByShopCartParam( String.valueOf(user.getUserId()), basketIdShopCartParamMap);
        }

        // 拿到购物车的所有item
        List<ShopCartItemDto> shopCartItems = basketService.getShopCartItems( String.valueOf(user.getUserId()));
        return success(basketService.getShopCarts(shopCartItems));

    }

    @DeleteMapping("/deleteItem")
    @Operation(summary = "删除用户购物车物品", description = "通过购物车id删除用户购物车物品")
    public AjaxResult deleteItem(@RequestBody List<Long> basketIds,HttpServletRequest request) {
        LoginUser user = tokenService.getLoginUser(request);
        basketService.deleteShopCartItemsByBasketIds(String.valueOf(user.getUserId()), basketIds);
        return success();
    }

    @DeleteMapping("/deleteAll")
    @Operation(summary = "清空用户购物车所有物品", description = "清空用户购物车所有物品")
    public AjaxResult deleteAll(HttpServletRequest request) {
        LoginUser user = tokenService.getLoginUser(request);
        basketService.deleteAllShopCartItems(String.valueOf(user.getUserId()));
        return success("删除成功");
    }

    @PostMapping("/changeItem")
    @Operation(summary = "添加、修改用户购物车物品", description = "通过商品id(prodId)、skuId、店铺Id(shopId),添加/修改用户购物车商品，并传入改变的商品个数(count)，" +
            "当count为正值时，增加商品数量，当count为负值时，将减去商品的数量，当最终count值小于0时，会将商品从购物车里面删除")
    public AjaxResult addItem(@Valid @RequestBody ChangeShopCartParam param,HttpServletRequest request) {
        LoginUser user = tokenService.getLoginUser(request);
        List<ShopCartItemDto> shopCartItems = basketService.getShopCartItems(String.valueOf(user.getUserId()));
        Product prodParam = productService.getProductByProdId(param.getProdId());
        Sku skuParam = skuService.getSkuBySkuId(param.getSkuId());

        // 当商品状态不正常时，不能添加到购物车
        for (ShopCartItemDto shopCartItemDto : shopCartItems) {
            if (Objects.equals(param.getSkuId(), shopCartItemDto.getSkuId())) {
                Basket basket = new Basket();
                basket.setUserId(String.valueOf(user.getUserId()));
                basket.setBasketCount((long) (param.getCount() + shopCartItemDto.getProdCount()));
                basket.setBasketId(shopCartItemDto.getBasketId());

                // 防止购物车变成负数
                if (basket.getBasketCount() <= 0) {
                    basketService.deleteShopCartItemsByBasketIds(String.valueOf(user.getUserId()), Collections.singletonList(basket.getBasketId()));
                    return success();
                }
                basketService.updateShopCartItem(basket);
                return success();
            }
        }
        // 所有都正常时
        basketService.addShopCartItem(param, String.valueOf(user.getUserId()));
        return success("添加成功");
    }

    @GetMapping("/prodCount")
    @Operation(summary = "获取购物车商品数量", description = "获取所有购物车商品数量")
    public AjaxResult prodCount(HttpServletRequest request) {
        LoginUser user = tokenService.getLoginUser(request);
        List<ShopCartItemDto> shopCartItems = basketService.getShopCartItems(String.valueOf(user.getUserId()));
        if (CollectionUtil.isEmpty(shopCartItems)) {
            return success(0);
        }
        Integer totalCount = shopCartItems.stream().map(ShopCartItemDto::getProdCount).reduce(0, Integer::sum);
        return success(totalCount);
    }

    @GetMapping("/expiryProdList")
    @Operation(summary = "获取购物车失效商品信息", description = "获取购物车失效商品列表")
    public AjaxResult expiryProdList(HttpServletRequest request) {
        LoginUser user = tokenService.getLoginUser(request);
        List<ShopCartItemDto> shopCartItems = basketService.getShopCartExpiryItems(String.valueOf(user.getUserId()));
        //根据店铺ID划分item
        Map<Long, List<ShopCartItemDto>> shopCartItemDtoMap = shopCartItems.stream().collect(Collectors.groupingBy(ShopCartItemDto::getShopId));

        // 返回一个店铺对应的所有信息
        List<ShopCartExpiryItemDto> shopcartExpiryitems = Lists.newArrayList();

        for (Long key : shopCartItemDtoMap.keySet()) {
            ShopCartExpiryItemDto shopCartExpiryItemDto = new ShopCartExpiryItemDto();
            shopCartExpiryItemDto.setShopId(key);
            List<ShopCartItemDto> shopCartItemDtos = Lists.newArrayList();
            for (ShopCartItemDto tempShopCartItemDto : shopCartItemDtoMap.get(key)) {
                shopCartExpiryItemDto.setShopName(tempShopCartItemDto.getShopName());
                shopCartItemDtos.add(tempShopCartItemDto);
            }
            shopCartExpiryItemDto.setShopCartItemDtoList(shopCartItemDtos);
            shopcartExpiryitems.add(shopCartExpiryItemDto);
        }

        return success(shopcartExpiryitems);
    }

    @DeleteMapping("/cleanExpiryProdList")
    @Operation(summary = "清空用户失效商品", description = "清空用户失效商品")
    public AjaxResult cleanExpiryProdList(HttpServletRequest request) {
        LoginUser user = tokenService.getLoginUser(request);
        basketService.cleanExpiryProdList(String.valueOf(user.getUserId()));
        return success();
    }

    @PostMapping("/totalPay")
    @Operation(summary = "获取选中购物项总计、选中的商品数量", description = "获取选中购物项总计、选中的商品数量,参数为购物车id数组")
    public AjaxResult getTotalPay(@RequestBody List<Long> basketIds,HttpServletRequest request) {
        LoginUser user = tokenService.getLoginUser(request);
        // 拿到购物车的所有item
        List<ShopCartItemDto> dbShopCartItems = basketService.getShopCartItems(String.valueOf(user.getUserId()));

        List<ShopCartItemDto> chooseShopCartItems = dbShopCartItems
                .stream()
                .filter(shopCartItemDto -> {
                    for (Long basketId : basketIds) {
                        if (Objects.equals(basketId, shopCartItemDto.getBasketId())) {
                            return true;
                        }
                    }
                    return false;
                })
                .collect(Collectors.toList());

        // 根据店铺ID划分item
        Map<Long, List<ShopCartItemDto>> shopCartMap = chooseShopCartItems.stream().collect(Collectors.groupingBy(ShopCartItemDto::getShopId));

        double total = 0.0;
        int count = 0;
        double reduce = 0.0;
        for (Long shopId : shopCartMap.keySet()) {
            //获取店铺的所有商品项
            List<ShopCartItemDto> shopCartItemDtoList = shopCartMap.get(shopId);
            // 构建每个店铺的购物车信息
            ShopCartDto shopCart = new ShopCartDto();
            shopCart.setShopId(shopId);

            applicationContext.publishEvent(new ShopCartEvent(shopCart, shopCartItemDtoList));

            List<ShopCartItemDiscountDto> shopCartItemDiscounts = shopCart.getShopCartItemDiscounts();

            for (ShopCartItemDiscountDto shopCartItemDiscount : shopCartItemDiscounts) {
                List<ShopCartItemDto> shopCartItems = shopCartItemDiscount.getShopCartItems();

                for (ShopCartItemDto shopCartItem : shopCartItems) {
                    count = shopCartItem.getProdCount() + count;
                    total = Arith.add(shopCartItem.getProductTotalAmount(), total);
                }
            }
        }
        ShopCartAmountDto shopCartAmountDto = new ShopCartAmountDto();
        shopCartAmountDto.setCount(count);
        shopCartAmountDto.setTotalMoney(total);
        shopCartAmountDto.setSubtractMoney(reduce);
        shopCartAmountDto.setFinalMoney(Arith.sub(shopCartAmountDto.getTotalMoney(), shopCartAmountDto.getSubtractMoney()));

        return success(shopCartAmountDto);
    }

}
